package com.ruoyi.datascreen.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.datascreen.domain.vo.DsCustomDataVo;
import com.ruoyi.datascreen.mapper.DsCustomDataMapper;
import com.ruoyi.lowcode.common.Lowcode;
import com.ruoyi.lowcode.domain.LcField;
import com.ruoyi.lowcode.domain.LcModel;
import com.ruoyi.lowcode.domain.vo.LcFieldVo;
import com.ruoyi.lowcode.enums.MysqlConditionalConstructor;
import com.ruoyi.lowcode.mapper.LcFieldMapper;
import com.ruoyi.lowcode.mapper.LcModelMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.datascreen.domain.bo.DsElementBo;
import com.ruoyi.datascreen.domain.vo.DsElementVo;
import com.ruoyi.datascreen.domain.DsElement;
import com.ruoyi.datascreen.mapper.DsElementMapper;
import com.ruoyi.datascreen.service.IDsElementService;

import java.util.List;
import java.util.Map;
import java.util.Collection;

/**
 * 大屏元素Service业务层处理
 *
 * @author ruoyi
 * @date 2023-11-19
 */
@RequiredArgsConstructor
@Service
public class DsElementServiceImpl implements IDsElementService {

    private final DsElementMapper baseMapper;

    private final Lowcode lowcode;

    private final DsCustomDataMapper customDataMapper;

    /**
     * 查询大屏元素
     */
    @Override
    public DsElementVo queryById(Long elementId) {
        return baseMapper.selectVoById(elementId);
    }

    /**
     * 大屏元素模型相关信息
     *
     * @param dsElementVo
     * @return
     */
    @Override
    public DsElementVo selectElementModel(DsElementVo dsElementVo) {
        dsElementVo.setModelVoList(lowcode.getModelById(dsElementVo.getElementModel()));
        dsElementVo.setExFieldVoList(lowcode.getFieldByModelIdAndDictionaryNotNull(dsElementVo.getElementModel()));
        dsElementVo.setEyFieldVoList(lowcode.getFieldByModelId(dsElementVo.getElementModel()));
        return dsElementVo;
    }

    @Override
    public JSONObject selectEchartsInfoById(Long elementId) throws ClassNotFoundException {
        DsElementVo dsElementVo = baseMapper.selectVoById(elementId);
        JSONObject data = new JSONObject();

        if("custom".equals(dsElementVo.getElementDataSources())){
            DsCustomDataVo customDataVo = customDataMapper.selectVoById(dsElementVo.getCustomId());
            data.put("seriesName", customDataVo.getCustomName());
            data.put("yAxis", JSONArray.parse(customDataVo.getTypeList()));
            data.put("series", JSONArray.parse(customDataVo.getDataList()));
        }else {
            // 数据来源为模型
            if ("pie".equals(dsElementVo.getElementType())) {
                data = lowcode.getEchartsInfoByElementForPie(dsElementVo.getElementModel(), dsElementVo.getExField());
            }else if("scatterplot".equals(dsElementVo.getElementType())){
                data = lowcode.getEchartsInfoByElementForScatterplot(
                        dsElementVo.getElementModel(),
                        dsElementVo.getExField(),
                        dsElementVo.getEyxField(),
                        dsElementVo.getEyyField()
                );
            }else{
                data = lowcode.getEchartsInfoByElement(dsElementVo.getElementModel(), dsElementVo.getExField(), dsElementVo.getEyData());
            }
        }

        data.put("element", dsElementVo);
        return data;
    }

    /**
     * 查询大屏元素列表
     */
    @Override
    public TableDataInfo<DsElementVo> queryPageList(DsElementBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<DsElement> lqw = buildQueryWrapper(bo);
        Page<DsElementVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询大屏元素列表
     */
    @Override
    public List<DsElementVo> queryList(DsElementBo bo) {
        LambdaQueryWrapper<DsElement> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<DsElement> buildQueryWrapper(DsElementBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<DsElement> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getElementName()), DsElement::getElementName, bo.getElementName());
        lqw.eq(StringUtils.isNotBlank(bo.getElementType()), DsElement::getElementType, bo.getElementType());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), DsElement::getStatus, bo.getStatus());
        return lqw;
    }

    /**
     * 新增大屏元素
     */
    @Override
    public Boolean insertByBo(DsElementBo bo) {
        DsElement add = BeanUtil.toBean(bo, DsElement.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setElementId(add.getElementId());
        }
        return flag;
    }

    /**
     * 修改大屏元素
     */
    @Override
    public Boolean updateByBo(DsElementBo bo) {
        DsElement update = BeanUtil.toBean(bo, DsElement.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(DsElement entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除大屏元素
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}
